home *** CD-ROM | disk | FTP | other *** search
- /*
- * FednetCmp - Fednet file compression/decompression
- * Single file savebox
- * Copyright (C) 2001 Chris Bazley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public Licence as published by
- * the Free Software Foundation; either version 2 of the Licence, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public Licence for more details.
- *
- * You should have received a copy of the GNU General Public Licence
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- /* ANSI library files */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdbool.h>
-
- /* RISC OS library files */
- #include "toolbox.h"
- #include "saveas.h"
- #include "window.h"
- #include "gadgets.h"
- #include "event.h"
- #include "flex.h"
-
- /* My library files */
- #include "err.h"
- #include "msgtrans.h"
- #include "Macros.h"
- #include "ViewsMenu.h"
- #include "SFformats.h"
- #include "NoBudge.h"
- #include "timer.h"
- #include "hourglass.h"
- #include "TboxBugs.h"
- #include "FilePerc.h"
-
- /* Local headers */
- #include "Utils.h"
- #include "Main.h"
- #include "SaveFile.h"
-
- /* gadget IDs */
- #define SAVEFILE_SSFILETYPE 0x01
-
- typedef struct _SaveFileBlk
- {
- ObjectId saveas_id;
- ObjectId window_id;
- char *reset_file_name;
- void *buffer;
- bool no_budge;
- bool compress;
- char reset_filetype[32];
- } SaveFileBlk;
-
- /* ----------------------------------------------------------------------- */
- /* Function prototypes */
-
- static ToolboxEventHandler _SaveFile_savehandler, _SaveFile_ramhandler, _SaveFile_typehandler, _SaveFile_savecompleted, _SaveFile_deletedhandler, _SaveFile_buttonshandler;
-
- /* ----------------------------------------------------------------------- */
- /* Public functions */
-
- ObjectId SaveFile_create(char *savepath, bool data_saved, flex_ptr buffer, bool compress)
- {
- /* Open savebox for data - if success, reanchors flex block. */
- SaveFileBlk *newblk;
- char *views_path, *list_tok, *obj_templ;
- int output_type;
-
- /* Grab memory */
- newblk = malloc(sizeof(SaveFileBlk));
- if(newblk == NULL)
- MG_RETV("NoMem", NULL_ObjectId) /* failure */
- newblk->reset_file_name = NULL;
- newblk->compress = compress;
- newblk->no_budge = false; /* we aren't preventing flex budging */
-
- if(compress) {
- /* Save data uncompressed */
- list_tok = "CompDialogueList";
- obj_templ = "SaveFednet";
- output_type = FILETYPE_FEDNET;
- }
- else {
- /* Save data compressed */
- list_tok = "DeCompDialogueList";
- obj_templ = "SaveFile";
- output_type = FILETYPE_DATA;
- }
-
- /* Create object */
- if(E(toolbox_create_object(0, obj_templ, &newblk->saveas_id)))
- goto errexit_free;
- if(compress) {
- /* Get ObjectId of custom compression savebox with filetype selection */
- if(E(saveas_get_window_id(0, newblk->saveas_id, &newblk->window_id)))
- goto errexit_delete;
- } else
- newblk->window_id = newblk->saveas_id;
-
- /* Store default settings */
- if((newblk->reset_file_name = copystring(savepath)) == NULL)
- goto errexit_delete;
- if(compress) {
- if(E(stringset_get_selected(0, newblk->window_id, SAVEFILE_SSFILETYPE, &newblk->reset_filetype, sizeof(newblk->reset_filetype), NULL)))
- goto errexit_delete;
- }
-
- /* Add entry to iconbar menu */
- if(data_saved)
- views_path = savepath; /* we have real filepath */
- else
- views_path = ""; /* dummy filepath */
- if(E(ViewsMenu_add(newblk->saveas_id, msgs_lookup_sub1(list_tok, tail(savepath, 3)), views_path)))
- goto errexit_delete;
-
- /* Set up window */
- if(E(saveas_set_file_name(0, newblk->saveas_id, savepath))
- || E(saveas_set_file_type(0, newblk->saveas_id, output_type))
- || E(saveas_set_file_size(0, newblk->saveas_id, flex_size(buffer))))
- goto errexit_menuremove;
-
- if(compress) {
- /* Register extra handler for filetype selection */
- if(E(event_register_toolbox_handler(newblk->window_id, StringSet_ValueChanged, _SaveFile_typehandler, newblk)))
- goto errexit_menuremove;
- }
-
- /* Register other handlers
- Note that ObjectDeleted handler is registered AFTER anything that could cause an error and therefore premature deletion!
- */
- if(E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_SaveToFile, _SaveFile_savehandler, newblk))
- || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_FillBuffer, _SaveFile_ramhandler, newblk))
- || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_SaveCompleted, _SaveFile_savecompleted, newblk))
- || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_DialogueCompleted, delete_object_handler, newblk))
- || E(event_register_toolbox_handler(newblk->window_id, ActionButton_Selected, _SaveFile_buttonshandler, newblk))
- || E(event_register_toolbox_handler(newblk->saveas_id, Toolbox_ObjectDeleted, _SaveFile_deletedhandler, newblk)))
- goto errexit_menuremove;
-
- flex_reanchor(&newblk->buffer, buffer);
- return newblk->saveas_id; /* success */
-
- errexit_menuremove:
- RE(ViewsMenu_remove(newblk->saveas_id));
- errexit_delete:
- RE(toolbox_delete_object(0, newblk->saveas_id));
- errexit_free:
- free(newblk->reset_file_name);
- free(newblk);
- return NULL_ObjectId;
- }
-
- /* ----------------------------------------------------------------------- */
- /* Private functions */
-
- /*
- * Toolbox event handlers
- */
-
- static int _SaveFile_typehandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- /* New file type selected from StringSet */
- StringSetValueChangedEvent *ssvce = (StringSetValueChangedEvent *)event;
- SaveFileBlk *blk = (SaveFileBlk *)handle;
-
- int hextype;
- sscanf(strchr(ssvce->string, '('), "(&%x)", &hextype);
- RE(saveas_set_file_type(0, blk->saveas_id, hextype))
-
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int _SaveFile_savehandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- SaveAsSaveToFileEvent *save_to_file_block = (SaveAsSaveToFileEvent *)event;
- SaveFileBlk *blk = (SaveFileBlk *)handle;
- unsigned int flags = 0;
-
- int file_type;
- if(E(saveas_get_file_type(0, id_block->self_id, &file_type)))
- goto exit;
-
- _kernel_oserror *err;
- if(!blk->compress)
- err = perc_operation(FILEPERC_OP_SAVE, save_to_file_block->filename, file_type, &blk->buffer);
- else
- err = perc_operation(FILEPERC_OP_COMP, save_to_file_block->filename, file_type, &blk->buffer);
- if(err != NULL)
- err_report(err->errnum, msgs_lookup_sub1("SaveFail", err->errmess));
- else
- flags = 1; /* success */
-
- exit:
- saveas_file_save_completed(flags, id_block->self_id, save_to_file_block->filename);
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int _SaveFile_ramhandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- SaveAsFillBufferEvent *fill_buffer_event = (SaveAsFillBufferEvent *)event;
- SaveFileBlk *blk = (SaveFileBlk *)handle;
- int bytes_to_go, chunk_size, buffer_size;
-
- if(blk->no_budge) {
- blk->no_budge = false;
- nobudge_deregister();
- }
-
- buffer_size = flex_size((flex_ptr)&blk->buffer);
-
- if(fill_buffer_event->no_bytes > buffer_size)
- /* Already sent all data */
- chunk_size = 0;
- else {
- /* Calculate bytes still to send */
- bytes_to_go = buffer_size - fill_buffer_event->no_bytes;
- if(bytes_to_go > fill_buffer_event->size)
- /* Can't fit remaining, so just fill buffer */
- chunk_size = fill_buffer_event->size;
- else
- /* Send all of remaining data */
- chunk_size = bytes_to_go;
- }
-
- nobudge_register(1024);
- blk->no_budge = true;
-
- RE(saveas_buffer_filled(0, id_block->self_id, (void *)((int)blk->buffer + fill_buffer_event->no_bytes), chunk_size))
-
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int _SaveFile_savecompleted(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- /* Save completed */
- SaveFileBlk *blk = (SaveFileBlk *)handle;
-
- if(blk->no_budge) {
- blk->no_budge = false;
- nobudge_deregister();
- }
-
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int _SaveFile_buttonshandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- ActionButtonSelectedEvent *abse = (ActionButtonSelectedEvent *)event;
- SaveFileBlk *blk = (SaveFileBlk *)handle;
-
- if(!FLAG_SET(abse->hdr.flags, ActionButton_Selected_Adjust))
- return 0; /* not interested */
-
- switch(id_block->self_component) {
- case 0x82bc02: /* Cancel button */
- /* Reset dbox state */
- if(blk->reset_file_name != NULL)
- RE(saveas_set_file_name(0, blk->saveas_id, blk->reset_file_name));
-
- RE(stringset_set_selected(0, id_block->self_id, SAVEFILE_SSFILETYPE, blk->reset_filetype));
- int hextype;
- sscanf(strchr(blk->reset_filetype, '('), "(&%x)", &hextype);
- RE(saveas_set_file_type(0, blk->saveas_id, hextype));
- break;
-
- #ifndef SAVEAS_CRAP /* no point saving state if dbox closes anyway */
- case 0x82bc03: /* Save button */
- /* Record dbox state */
- RE(stringset_get_selected(0, id_block->self_id, SAVEFILE_SSFILETYPE, &blk->reset_filetype, sizeof(blk->reset_filetype), NULL));
-
- int len;
- E_RETV(saveas_get_file_name(0, blk->saveas_id, NULL, 0, &len), 1)
- free(blk->reset_file_name);
- blk->reset_file_name = malloc(len+1);
- if(blk->reset_file_name == NULL)
- err_complain(255, msgs_global("NoMem"));
- else
- RE(saveas_get_file_name(0, blk->saveas_id, blk->reset_file_name, len, NULL))
- break;
- #endif
-
- default:
- return 0; /* unknown component */
- }
-
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int _SaveFile_deletedhandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- SaveFileBlk *blk = (SaveFileBlk *)handle;
-
- if(blk->no_budge) {
- blk->no_budge = false;
- nobudge_deregister();
- }
-
- /* Deregister handlers */
- RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_SaveToFile, _SaveFile_savehandler, handle));
- RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_FillBuffer, _SaveFile_ramhandler, handle));
- RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_SaveCompleted, _SaveFile_savecompleted, handle));
- RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_DialogueCompleted, delete_object_handler, handle));
- RE(event_deregister_toolbox_handler(blk->window_id, ActionButton_Selected, _SaveFile_buttonshandler, handle));
- RE(event_deregister_toolbox_handler(id_block->self_id, Toolbox_ObjectDeleted, _SaveFile_deletedhandler, handle));
-
- if(blk->compress)
- /* Deregister extra handler for filetype selection */
- RE(event_deregister_toolbox_handler(blk->window_id, StringSet_ValueChanged, _SaveFile_typehandler, handle));
-
- /* Remove from iconbar menu */
- RE(ViewsMenu_remove(id_block->self_id));
-
- /* free memory */
- flex_free(&blk->buffer);
- free(blk->reset_file_name);
- free(blk);
-
- if(last_savebox == id_block->self_id)
- last_savebox = NULL_ObjectId;
-
- return 1; /* claim event */
- }
-